GoF 對備忘錄模式(Memento)的定義是:
「在不違反封裝的原則下,取得一個物件的內部狀態並保留在外部,讓該物件可以在日後恢復到原先保留的狀態。」
以存檔機制來說的話,就是希望有個可以將存檔的資料儲存起來的方式,並在需要的時候從存檔資料讀進遊戲裡設定,下面會先舉例一般例子的範例。
Memento.cs
namespace LinXuan.DesignPattern.Example.Memento
{
public class Memento
{
string m_SaveData;
public string GetSaveData()
{
return m_SaveData;
}
public void SetSaveData(string saveData)
{
m_SaveData = saveData;
}
}
}
Originator.cs
using UnityEngine;
namespace LinXuan.DesignPattern.Example.Memento
{
public class Originator
{
string m_SaveData;
public void SetInfo(string saveData)
{
m_SaveData = saveData;
}
public void ShowInfo()
{
Debug.Log("Originator State:" + m_SaveData);
}
public Memento CreateMemento()
{
Memento newMemento = new Memento();
newMemento.SetSaveData(m_SaveData);
return newMemento;
}
public void SetMemento(Memento memento)
{
m_SaveData = memento.GetSaveData();
}
}
}
MementoTest.cs
using UnityEngine;
namespace LinXuan.DesignPattern.Example.Memento
{
public class MementoTest : MonoBehaviour
{
private Originator m_Originator = new Originator();
void Start()
{
m_Originator.SetInfo("Step1");
m_Originator.ShowInfo();
Memento memento = m_Originator.CreateMemento();
m_Originator.SetInfo("Step2");
m_Originator.ShowInfo();
m_Originator.SetMemento(memento);
m_Originator.ShowInfo();
}
}
}
輸出如下
流離之歌這款遊戲用來製作存檔機制的程式主要會用Easy Save 3,如果沒有的話可以用Unity內建的PlayerPrefs製作類似的功能
不過這邊的程式碼其實寫的不算太好,有機會的話是想要在優化一下就是...
CALSaveSystem.cs
using LuLuBearStudio.Save;
using System.Collections.Generic;
using UnityEngine;
public class CALSaveSystem : MonoBehaviour
{
[SerializeField] private bool m_IsTest = false;
[SerializeField] private SaveDataSO m_SaveDataSO;//用ScriptableObject製作的暫時存檔,
[SerializeField] private int m_InitinalScene = 1;
private int defaultResolutionIndex;
public bool CurrentSceneDialogueIsComplete { set => m_SaveDataSO.CurrentSceneDialogueIsComplete = value; get => m_SaveDataSO.CurrentSceneDialogueIsComplete; }
public bool IsBattleScene { set => m_SaveDataSO.IsBattleScene = value; get => m_SaveDataSO.IsBattleScene; }
public int EndSceneNumber => m_SaveDataSO.EndSceneNumber;
public int InitinalSceneNumber => m_SaveDataSO.InitinalSceneNumber;
public SaveDataSO SaveDataSO => m_SaveDataSO;
public void SaveCurrentScene(int sceneNumber)
{
m_SaveDataSO.SceneNumber = sceneNumber;
if(!m_IsTest)
ES3.Save("mySaveData", m_SaveDataSO.SceneNumber); //ES3.Save的存檔到電腦資料夾的部分
}
public void SaveResData()
{
if(!m_IsTest)
ES3.Save("userResItem", m_SaveDataSO.UserResItem);
}
public void SaveAudioSaveData()
{
if(!m_IsTest)
ES3.Save("audioVolSaveData", m_SaveDataSO.AudioVolSaveData);
}
public int LoadSceneNumber()
{
return m_SaveDataSO.SceneNumber;
}
public void LoadAllSaveData()
{
LoadSceneSaveData();
LoadAudioSaveData();
LoadResItemSaveData();
}
public void LoadSceneSaveData()
{
if (ES3.KeyExists("mySaveData") && !m_IsTest) //如果ES3可以從電腦存檔的資料夾讀取到資料,就會把資料讀取出來儲存在SaveDataSO裡
{
m_SaveDataSO.SceneNumber = ES3.Load<int>("mySaveData");
}
}
public void LoadAudioSaveData()
{
if(ES3.KeyExists("audioVolSaveData") && !m_IsTest)
{
m_SaveDataSO.AudioVolSaveData = ES3.Load<AudioVolSaveData>("audioVolSaveData");
}
}
public void LoadResItemSaveData()
{
if (ES3.KeyExists("userResItem") && !m_IsTest)
{
m_SaveDataSO.UserResItem = ES3.Load<ResItem>("userResItem");
}
else
{
ResolutionInitinal();
}
}
public void RestartGame()
{
m_SaveDataSO.SceneNumber = m_InitinalScene;
if(!m_IsTest)
ES3.Save("mySaveData", m_SaveDataSO.SceneNumber);
}
private void ResolutionInitinal()
{
//Resolution initinalize...
}
}
設計模式與遊戲開發的完美結合(暢銷回饋版)
Turn Based Strategy Framework
流離之歌